﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
using System.Threading.Tasks;
using Urs.Core;
using Urs.Core.Caching;
using Urs.Data.Domain.Stores;
using Urs.Data.Domain.Users;
using Urs.Data.Domain.Configuration;
using Plugin.Api.Models.Order;
using Plugin.Api.Models.GoodsReview;
using Urs.Services.Stores;
using Urs.Services.Users;
using Urs.Services.Localization;
using Urs.Services.Media;
using Urs.Services.Orders;
using Urs.Services.Security;
using Urs.Framework;
using Urs.Framework.Controllers;

namespace Plugin.Api.Controllers
{
    /// <summary>
    /// 商品评论接口
    /// </summary>
    [ApiVersion("1.0")]
    [Route("api/v{version:apiVersion}/goodsreview")]
    [ApiController]
    public class ReviewController : BaseApiController
    {
        private readonly ILocalizationService _localizationService;
        private readonly IUserService _userService;
        private readonly IWorkContext _workContext;
        private readonly MediaSettings _mediaSettings;
        private readonly IGoodsService _goodsService;
        private readonly IPermissionService _permissionService;
        private readonly ICacheManager _cacheManager;
        private readonly IPictureService _pictureService;
        private readonly IWebHelper _webHelper;
        private readonly StoreSettings _storeSettings;
        private readonly IOrderService _orderService;
        private readonly IOrderProcessingService _orderProcessingService;

        /// <summary>
        /// 构造器
        /// </summary>
        public ReviewController(ILocalizationService localizationService,
            IUserService userService,
            IWorkContext workContext,
            MediaSettings mediaSettings,
            IGoodsService goodsService,
            IPermissionService permissionService,
            ICacheManager cacheManager,
            IPictureService pictureService,
            IWebHelper webHelper,
            StoreSettings storeSettings,
            IOrderService orderService,
            IOrderProcessingService orderProcessingService)
        {
            this._localizationService = localizationService;
            this._userService = userService;
            this._workContext = workContext;
            this._mediaSettings = mediaSettings;
            this._goodsService = goodsService;
            this._permissionService = permissionService;
            this._cacheManager = cacheManager;
            this._pictureService = pictureService;
            this._webHelper = webHelper;
            this._storeSettings = storeSettings;
            this._orderService = orderService;
            this._orderProcessingService = orderProcessingService;
        }

        #region Utilities


        [NonAction]
        protected MoGoodsReviewList PrepareGoodsReviewsModel(PagingFiltering command, int goodsId = 0)
        {
            var model = new MoGoodsReviewList();

            if (command.PageSize <= 0) command.PageSize = command.PageSize > 0 ? command.PageSize : 5;
            if (command.PageNumber <= 0) command.PageNumber = 1;

            var goodsReviews = _goodsService.GetGoodsReviews(goodsId, null, null, true, pageIndex: command.PageIndex, pageSize: command.PageSize);

            model.GoodsId = goodsId;
            model.Paging.Page = command.PageNumber;
            model.Paging.Size = command.PageSize;
            model.Paging.TotalPage = goodsReviews.TotalPages;

            var users = _userService.GetUsersByIds(goodsReviews.Select(q => q.UserId).ToArray());
            foreach (var pr in goodsReviews)
            {
                model.GoodsReviews.Add(new MoGoodsReview()
                {
                    Id = pr.Id,
                    UserId = pr.UserId,
                    UserName = users.FirstOrDefault(c => c.Id == pr.UserId)?.FormatUserName(),
                    Title = pr.Title,
                    ReviewText = pr.ReviewText,
                    Rating = pr.Rating,
                    CreateTime = pr.CreateTime.ToString("g"),
                });
            }

            return model;
        }

        [NonAction]
        protected void PrepareGoodsReviewCreateModel(User user, GoodsReview entity, MoReviewRequest model)
        {
            if (entity == null)
                throw new ArgumentNullException("entity");

            if (model == null)
                throw new ArgumentNullException("model");

            int rating = model.Rating;
            if (rating < 1 || rating > 5) rating = 5;

            entity.UserId = user.Id;
            entity.OrderId = model.OrderId;
            entity.GoodsId = model.GoodsId;
            entity.IpAddress = _webHelper.GetCurrentIpAddress();
            entity.Rating = model.Rating;
            entity.ReviewText = model.ReviewText;
            entity.Title = model.Title;
            entity.CreateTime = DateTime.Now;
        }
        #endregion

        /// <summary>
        /// 获取评论列表
        /// </summary>
        /// <param name="pId">商品Id</param>
        /// <param name="page">页码（默认：1）</param>
        /// <param name="size">页大小（默认值：12）</param>
        /// <returns></returns>
        [HttpGet("list")]
        public async Task<ApiResponse<MoGoodsReviewList>> Get(int pId, int page = 1, int size = 12)
        {
            var goods = _goodsService.GetGoodsById(pId);
            if (goods == null || goods.Deleted || !goods.Published)
                return ApiResponse<MoGoodsReviewList>.NotFound();

            var data = await Task.Run(() =>
            {
                var command = new PagingFiltering
                {
                    PageNumber = page,
                    PageSize = size
                };
                return PrepareGoodsReviewsModel(command,pId);
            });

            return ApiResponse<MoGoodsReviewList>.Success(data);
        }

        /// <summary>
        /// 提交评论[Auth]
        /// </summary>
        /// <param name="model">商品评论对象</param>
        /// <returns></returns>
        [Authorize]
        [HttpGet("submit")]
        public async Task<ApiResponse> Submit(MoReviewRequest model)
        {
            var user = _workContext.CurrentUser;

            if (user == null || user.IsGuest())
                return ApiResponse.Warn(_localizationService.GetResource("Account.UnRegistered"));

            var order = _orderService.GetOrderById(model.OrderId);

            if (order.UserId != user.Id)
                return ApiResponse.Warn(_localizationService.GetResource("Account.UnRegistered"));

            if (!_orderProcessingService.IsReviewAllowed(order))
                return ApiResponse.Warn("订单状态不正确");

            var goods = _goodsService.GetGoodsById(model.GoodsId);
            if (goods == null || goods.Deleted)
                return ApiResponse.Warn("商品不正确");

            var entity = new GoodsReview();
            PrepareGoodsReviewCreateModel(user, entity, model);

            _goodsService.InsertGoodsReview(entity);
            //update goods totals
            _goodsService.UpdateGoodsReviewTotals(goods);

            var finish = true;
            foreach (var item in order.orderItems)
            {
                var goodsReview = _goodsService.GetGoodsReview(item.GoodsId, item.OrderId);
                if (goodsReview == null)
                    finish = false;
            }

            if (finish)
                _orderProcessingService.Complete(order.Id, false);

            return ApiResponse.Success();
        }

    }
}
